package com.jintian.smart.kernel.flowable.component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

import com.jintian.smart.kernel.core.flow.FlowAction;
import com.jintian.smart.kernel.core.flow.ITaskOperation;
import com.jintian.smart.kernel.core.flow.ProcessControl;
import com.jintian.smart.kernel.flowable.context.DefaultProcessContext;
import com.jintian.smart.kernel.flowable.engine.AbstractProcessStarter;
import org.apache.dubbo.config.annotation.DubboService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.TaskInfo;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Component
@DubboService(timeout = 5000)
public class DefaultProcessStarter extends AbstractProcessStarter {
    @Autowired
    private ITaskOperation<List<TaskInfo>> taskOperation;

    @Override
    protected List<TaskInfo> innerExecute(String process, String businessKey, ProcessControl processControl) throws Exception {
        try (DefaultProcessContext context = (DefaultProcessContext) this.processContextProvider.createInstance(process,
                null, FlowAction.start, null, null, businessKey, processControl);) {
            this.beforeStart(process, null, context);
            DefaultProcessStarter self = this;
            List<TaskInfo> ret = this.invokeAction(context, new Callable<List<TaskInfo>>() {
                @Override
                public List<TaskInfo> call() throws Exception {
                    return self.executeStart(process, businessKey, (DefaultProcessContext) context);
                }
            });
            // 启动后立即流转
            if (Boolean.TRUE.equals(context.getVariablesLocal().get(FlowAction.VARNAME_COMPLETE_AFTER_START))
                    || Boolean.TRUE.equals(context.getTransientVariablesLocal().get(FlowAction.VARNAME_COMPLETE_AFTER_START))
                    || Boolean.TRUE.equals(context.getTransientVariables().get(FlowAction.VARNAME_COMPLETE_AFTER_START))) {
                List<TaskInfo> nexts = new ArrayList<>();
                for (TaskInfo task : ret) {
                    processControl = ((DefaultTaskOperation) taskOperation).queryProcessControl(task.getId(), FlowAction.complete.name(), context.getTransientVariables());
                    // processControl = this.queryProcessControl(this.currentProcessContext().getAction(), task.getId(), context.getTransientVariables());
                    nexts.addAll(taskOperation.complete(task.getId(), processControl));
                }
                return nexts;
            }
            return ret;
        }
    }

    private List<TaskInfo> executeStart(String process, String businessKey, DefaultProcessContext context) {
        ProcessInstance pi = this.runtimeService().createProcessInstanceQuery()
                .processInstanceBusinessKey(businessKey).processDefinitionKey(process).singleResult();
        if (pi != null) {
            // 同一业务不允许重复启动
            throw new IllegalArgumentException("业务ID[" + businessKey + "]存在正在办理的流程");
        }
        pi = runtimeService().startProcessInstanceByKey(process, businessKey, context.getVariables());
        context.setProcessInstanceId(pi.getProcessInstanceId());
        List<TaskInfo> newTasks = ProcessContextProvider.getCurrentProcessContext().getNewTasks();
        // if (activity != null) {
        // Iterator<TaskInfo> itor = newTasks.iterator();
        // List<String> removeIds = new ArrayList<>();
        // while (itor.hasNext()) {
        // TaskEntity task = (TaskEntity) itor.next();
        // if (!activity.equals(task.getTaskDefinitionKey())) {
        // removeIds.add(task.getId());
        // itor.remove();
        // } else if (executors != null) {
        //
        // }
        // }
        // // this.taskService().deleteTasks(removeIds, true);
        // }
        for (TaskInfo t : newTasks) {
            checkNewTaskExecutor((TaskEntity) t);
        }
        return newTasks;
    }
}
